package blue.http.internal.core.parser;

import blue.base.core.path.FilePath;
import blue.base.core.reflect.BeanMethod;
import blue.base.core.reflect.JavaBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Jin Zheng
 * @since 1.0 2021-08-05
 */
public abstract class AbstractParser implements Parser {
	private static Logger logger = LoggerFactory.getLogger(AbstractParser.class);

	protected final Set<Class<?>> parserClassSet = new HashSet<>();

	public AbstractParser() {
	}

	@Override
	public final void parse(JavaBean bean) {
		if (parserClassSet.contains(bean.getTargetClass())) {
			logger.warn("{} has bean parsed", bean.getTargetClass().getName());
			return;
		}

		var rootPath = this.getRootPath(bean);
		if (logger.isDebugEnabled()) {
			logger.debug("Parse {}, root uri: {}", bean.getTargetClass().getName(), rootPath.getOriginalPath());
		}
		List<BeanMethod> methodList = bean.getAllMethods();
		for (var method : methodList) {
			if (!Modifier.isPublic(method.getModifiers())) {
				continue;
			}

			this.parseMethod(bean, method, rootPath);
		}

		parserClassSet.add(bean.getTargetClass());
	}

	protected abstract void parseMethod(JavaBean bean, BeanMethod method, FilePath rootPath);

	protected abstract FilePath getRootPath(JavaBean bean);
}
